<template>
  <div class="article-comment">
    <div ref="commentBoxRef" class="comment-box">
      <!-- 评论输入区 -->
      <div class="comment-editor">
        <h3 class="title">
          <PhChatCircleDots :size="20" color="#60a5fa" />
          {{ currentReplyTo ? '回复评论' : '发表评论' }}
          <span v-if="currentReplyTo" class="reply-info">
            回复 @{{ currentReplyTo.nickname }}
            <button class="cancel-reply" @click="cancelReply">取消回复</button>
          </span>
        </h3>

        <!-- 未登录状态 -->
        <div v-if="!userStore.isLoggedIn" class="login-tip">
          <p>请先登录后发表评论</p>
          <button class="login-btn" @click="visible = true">去登录</button>
        </div>

        <!-- 已登录状态 -->
        <div v-else class="editor-container">
          <div class="user-info">
            <img :src="userStore.avatar || '/src/assets/default-avatar.png'" class="avatar" alt="avatar" />
            <span class="nickname">{{ userStore.nickname }}</span>
          </div>
          <textarea
            v-model="commentContent"
            class="comment-textarea"
            :placeholder="currentReplyTo ? `回复 @${currentReplyTo.nickname}` : '写下你的评论...'"
            :rows="4"
          ></textarea>
          <div class="editor-footer">
            <button class="submit-btn" @click="submitComment" :disabled="!canSubmit">
              {{ currentReplyTo ? '发表回复' : '发表评论' }}
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 评论列表 -->
    <div class="comment-list">
      <div class="list-header">
        <h3 class="title">
          全部评论
          <span class="count">({{ totalComments }})</span>
        </h3>

        <div class="sort-options">
          <button
            class="sort-btn"
            :class="{ active: sortType === 'latest' }"
            @click="sortType = 'latest'"
          >
            最新
          </button>
          <button
            class="sort-btn"
            :class="{ active: sortType === 'popular' }"
            @click="sortType = 'popular'"
          >
            最热
          </button>
        </div>
      </div>

      <div v-if="comments.length === 0" class="empty-comment">
        暂无评论，快来抢沙发吧！
      </div>

      <div v-else class="comment-items">
        <CommentItem
          v-for="comment in sortedComments"
          :key="comment.id"
          :comment="comment"
          :article-author-id="articleAuthorId"
          @reply="handleReply"
          @like="handleLike"
          @dislike="handleDisLike"
        />
      </div>
    </div>
  </div>
  <LoginModal :visible="visible" @update:visible="args => visible = args"/>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import { useCommentStore, useUserStore } from '@/stores';
import { PhChatCircleText, PhChatCircleDots } from '@phosphor-icons/vue';
import type { Comment, LikeDislikeParams, Reply } from '@/types/comment';
import CommentItem from './CommentItem.vue';
import { createComment, dislikeComment, getCommentsByArticleId, likeComment } from '@/api/comment';
import LoginModal from '@/components/login-modal.vue';
import type { CommentSubmitParams } from '@/api/comment/types.ts';
import Message from '@/components/message';
import storage from '@/hooks/storage.ts';

const props = defineProps<{
  articleId: string;
  articleAuthorId: string;
}>();

const emit = defineEmits<{
  (e: 'showLogin'): void;
}>();

const userStore = useUserStore();
const commentStore = useCommentStore();
const visible = ref(false);
const comments = ref<Comment[]>([]);
const commentContent = ref('');
const currentReplyTo = ref<(Comment | Reply) | null>(null);
const sortType = ref<'latest' | 'popular'>('latest');
const commentBoxRef = ref<HTMLElement | null>(null);
const parentComment = ref<Comment>();
const commentLimit = ref(false);

// 滚动到评论框
const scrollToCommentBox = () => {
  if (commentBoxRef.value) {
    commentBoxRef.value.scrollIntoView({
      behavior: 'smooth',
      block: 'center'
    });
  }
};

// 监听刷新状态
watch(
  () => commentStore.needRefresh,
  (newValue) => {
    if (newValue) {
      fetchComments();
      commentStore.setNeedRefresh(false);
    }
  }
);

// 计算总评论数
const totalComments = computed(() => {
  return comments.value.reduce((total, comment) => {
    // 评论本身计数为1，加上所有回复的数量
    return total + 1 + (comment.replyList?.length || 0);
  }, 0);
});

// 评论是否可提交
const canSubmit = computed(() => {
  return commentContent.value.trim().length > 0;
});

// 排序后的评论列表
const sortedComments = computed(() => {
  return [...comments.value].sort((a, b) => {
    if (sortType.value === 'latest') {
      return new Date(b.createTime).getTime() - new Date(a.createTime).getTime();
    } else {
      return b.likes - a.likes;
    }
  });
});

// 获取评论列表
const fetchComments = async () => {
  try {
    const result = await getCommentsByArticleId({
      articleId: props.articleId,
      userId: userStore.id,
    });
    comments.value = result.data;
  } catch (error) {
    throw error;
  }
};

// 处理回复
const handleReply = (data: { comment: Comment | Reply; parentComment?: Comment }) => {
  currentReplyTo.value = data.comment;
  parentComment.value = data.parentComment;
  scrollToCommentBox();
};

// 取消回复
const cancelReply = () => {
  currentReplyTo.value = null;
  parentComment.value = undefined;
  commentContent.value = '';
};

// 评论频率限制
const COMMENT_COOLDOWN = 60000; // 60秒冷却时间

const checkCommentLimit = () => {
  const lastCommentTime = storage.get('lastCommentTime');
  const now = Date.now();

  if (lastCommentTime) {
    const timeSinceLastComment = now - Number(lastCommentTime);
    if (timeSinceLastComment < COMMENT_COOLDOWN) {
      const remainingTime = Math.ceil((COMMENT_COOLDOWN - timeSinceLastComment) / 1000);
      Message.error(`评论太频繁，请等待 ${remainingTime} 秒后再试`);
      commentLimit.value = true;
    }else {
      commentLimit.value = false;
    }
  }

  storage.set('lastCommentTime', String(now));
};

// 提交评论
// 提交评论
const submitComment = async () => {
  if (!canSubmit.value || !userStore.id) return;

  try {
    const params: CommentSubmitParams = currentReplyTo.value
      ? {
        content: commentContent.value,
        articleId: props.articleId,
        commentId: parentComment.value?.id || currentReplyTo.value.id,
        targetUserId: currentReplyTo.value.userId,
        parentId: 'parentId' in currentReplyTo.value ? currentReplyTo.value.id : null,
        isReply: true,
        userId: userStore.id, // 现在确保 userStore.id 一定存在
      }
      : {
        content: commentContent.value,
        articleId: props.articleId,
        isReply: false,
        userId: userStore.id, // 现在确保 userStore.id 一定存在
      };

    // 检查发送频率限制
    checkCommentLimit();
    if (!commentLimit.value) {
      await createComment(params);
      Message.success('发表成功');
      commentContent.value = '';
      currentReplyTo.value = null;
      parentComment.value = undefined;
      await fetchComments();
    }
  } catch (error) {
    throw error;
  }
};

// 处理点赞
const handleLike = async (data: LikeDislikeParams) => {
  if (!userStore.isLoggedIn) {
    emit('showLogin');
    return;
  }

  try {
    await likeComment({
      targetId: data.id,
      targetType: data.type,
      userId: userStore.id,
      actionType: true,
      articleId: props.articleId
    });
    await fetchComments();
  } catch (error) {
    throw error;
  }
};

// 处理点踩
const handleDisLike = async (data: LikeDislikeParams) => {
  if (!userStore.isLoggedIn) {
    emit('showLogin');
    return;
  }

  try {
    await dislikeComment({
      targetId: data.id,
      targetType: data.type,
      userId: userStore.id,
      actionType: false,
      articleId: props.articleId
    });
    await fetchComments();
  } catch (error) {
    throw error;
  }
};

onMounted(() => {
  fetchComments();
});
</script>

<style scoped lang="less">
.article-comment {
  padding: 24px 40px;
  border-top: 1px solid #eaecef;
  box-sizing: border-box;
  border-radius: 0 0 12px 12px;

  .comment-editor {
    margin-bottom: 48px;

    .title {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 16px;
      font-weight: 500;
      color: #1a1a1a;
      margin-bottom: 20px;

      .reply-info {
        margin-left: 8px;
        font-size: 14px;
        color: #666;
        font-weight: normal;

        .cancel-reply {
          margin-left: 8px;
          color: #3b82f6;
          background: none;
          border: none;
          cursor: pointer;
          padding: 2px 8px;
          border-radius: 4px;

          &:hover {
            background: #eff6ff;
          }
        }
      }
    }

    .login-tip {
      text-align: center;
      padding: 32px;
      margin: 0 -20px;
      background: #f9fafb;
      border-radius: 8px;

      p {
        color: #666;
        margin-bottom: 16px;
      }

      .login-btn {
        padding: 8px 24px;
        background: #3b82f6;
        color: #fff;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        transition: all 0.2s;

        &:hover {
          background: #2563eb;
        }
      }
    }

    .editor-container {
      .user-info {
        display: flex;
        align-items: center;
        gap: 12px;
        margin-bottom: 16px;

        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          object-fit: cover;
        }

        .nickname {
          font-size: 15px;
          color: #1f2937;
          font-weight: 500;
        }
      }

      .comment-textarea {
        width: 100%;
        box-sizing: border-box;
        padding: 12px 16px;
        border: 1px solid #e5e7eb;
        border-radius: 8px;
        resize: vertical;
        min-height: 100px;
        font-size: 14px;
        line-height: 1.6;
        color: #1f2937;
        transition: all 0.2s;
        background: #f9fafb;

        &:focus {
          outline: none;
          border-color: #3b82f6;
          background: #fff;
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
        }

        &::placeholder {
          color: #9ca3af;
        }
      }

      .editor-footer {
        display: flex;
        justify-content: flex-end;
        margin-top: 16px;

        .submit-btn {
          padding: 8px 24px;
          background: #3b82f6;
          color: #fff;
          border: none;
          border-radius: 6px;
          cursor: pointer;
          font-size: 14px;
          transition: all 0.2s;

          &:hover {
            background: #2563eb;
          }

          &:disabled {
            background: #93c5fd;
            cursor: not-allowed;
          }
        }
      }
    }
  }

  .comment-list {
    .list-header {
      padding: 0 0 20px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border-bottom: 1px solid #eaecef;

      .title {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 16px;
        font-weight: 500;
        color: #1a1a1a;

        .count {
          color: #6b7280;
          font-weight: normal;
          margin-left: 4px;
        }
      }

      .sort-options {
        display: flex;
        gap: 8px;

        .sort-btn {
          padding: 6px 12px;
          border: none;
          background: none;
          color: #6b7280;
          font-size: 14px;
          cursor: pointer;
          border-radius: 6px;
          transition: all 0.2s;

          &:hover {
            background: #f3f4f6;
          }

          &.active {
            color: #3b82f6;
            background: #eff6ff;
            font-weight: 500;
          }
        }
      }
    }

    .empty-comment {
      text-align: center;
      padding: 48px 0;
      color: #6b7280;
      font-size: 15px;
    }

    .comment-items {
      padding: 0;
    }
  }
}

@media (max-width: 768px) {
  .article-comment {
    padding: 24px 20px;

    .comment-editor {
      .login-tip {
        margin: 0 -10px;
      }
    }
  }
}

@media (max-width: 576px) {
  .article-comment {
    margin-top: 0;
    padding: 24px 16px;

    .comment-editor {
      .login-tip {
        margin: 0 -8px;
      }
    }
  }
}
</style>
